#include "../include/TaskQueue.h"

namespace myNameSpace {
TaskQueue::TaskQueue(size_t queueSize): _queue(), _queueSize(queueSize), _mutex(), _notFull(_mutex), _notEmpty(_mutex), _isWorking(true) {} 

void TaskQueue::push(ElemType &&taskCallback) {
    _mutex.lock();
    while (full()) {
        _notFull.wait();
    }
    _queue.push(std::move(taskCallback));
    _notEmpty.notify();
    _mutex.unlock();
}

TaskQueue::ElemType TaskQueue::pop() {
    _mutex.lock();
    while (empty() && _isWorking) {
        _notEmpty.wait();
    }
    if (_isWorking) {
        ElemType pTask = _queue.front();
        _queue.pop();
        _notFull.notify();
        _mutex.unlock();
        return pTask;
    }
    _mutex.unlock();
    return nullptr;
}

void TaskQueue::wakeUp() {
    _isWorking = false;
    _notEmpty.notifyAll();
}

bool TaskQueue::empty() {
    return 0 == _queue.size();
}

bool TaskQueue::full() {
    return _queue.size() == _queueSize;
}
} // end of namespace myNameSpace
